﻿using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Sherwood.Content.Contracts;
using Sherwood.Content.Tests;
using Sherwood.Content.UpdateServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using Sherwood.Content.UpdateServices.Tests.Properties;
using Microsoft.Practices.ObjectBuilder2;

namespace Sherwood.Content.UpdateServices.Tests
{
    /// <summary>
    ///This is a test class for XmlUpdateServiceTest and is intended
    ///to contain all XmlUpdateServiceTest Unit Tests
    ///</summary>
    [TestClass()]
    public class XmlUpdateServiceTest : MockedUpdateEnvironment
    {
        private TestContext _testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return _testContextInstance;
            }
            set
            {
                _testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod()]
        public void Test_normal_record_and_meta_submission()
        {
            var target = new XmlUpdateService<IRecord>();
            var xml = Resources.UpdateRecordsRequest;

            var request = updateRecordsRequest.Parse(xml);
            request.Sign(SampleClient.PrivateKey);

            target.UpdateRecords(request.GetAsMemoryStream());

            Mocks.Verify();
        }

        [TestMethod]
        public void Create_with_other_client_id_throws_exception()
        {
            var target = new XmlUpdateService<IRecord>();

            Records
                .Setup(r => r.GetByReferenceId("WRONG", "1"))
                .Returns(() => null)
                .Verifiable();

            var xml =
                @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<updateRecordsRequest xmlns=""Sherwood.Content.Contracts"">
  <content>
    <record clientId=""WRONG"" referenceId=""1"" updateMode=""CreateOrUpdate"" />
  </content>
  <client id=""SampleClient"">
    <signature />
  </client>
</updateRecordsRequest>";

            var request = updateRecordsRequest.Parse(xml);
            request.Sign(SampleClient.PrivateKey);
            
            Assert.IsTrue(new StreamReader(target.UpdateRecords(request.GetAsMemoryStream())).ReadToEnd().Contains("InvalidOperationException"));
        }

        [TestMethod]
        public void Record_without_identification_throws_exception()
        {
            var target = new XmlUpdateService<IRecord>();

            Records
                .Setup(r => r.GetByReferenceId("WRONG", "1"))
                .Returns(() => null)
                .Verifiable();

            var xml =
                @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<updateRecordsRequest xmlns=""Sherwood.Content.Contracts"">
  <content>
    <record updateMode=""CreateOrUpdate"" />
  </content>
  <client id=""SampleClient"">
    <signature />
  </client>
</updateRecordsRequest>";

            var request = updateRecordsRequest.Parse(xml);
            request.Sign(SampleClient.PrivateKey);

            var result = new StreamReader(target.UpdateRecords(request.GetAsMemoryStream())).ReadToEnd();
            Console.Write(result);
            Assert.IsTrue(result.Contains("ArgumentException"));
        }
    }
}
